#library('qdart');
#import('dart:html');

/*
 finished:
 + $(Node), $(String)
 + .each(function(index, value))
 + .html(), .html(value)
 + .attr(key), .attr(key, Map), .attr(key, value)
 + .click(), .click(function(e))
 + .addClass(String class), .addClass(function(index, value))
 + .hasClass(String name)
 + .removeClass(), .removeClass(String name)
 + .toggleClass(String name), .toggleClass(String name, bool switch)
 + jQuery.now()


*/

class Dom {
  List<Node> _nodelist;

  Dom(this._nodelist);
  
  first() {
    if (_nodelist.length == 0)
      return null;
    List<Node> nl = new List<Node>();
    nl.add(_nodelist[0]);
    return new Dom(nl);
  }
  
  void each(fn) {
    for(var i = 0; i < _nodelist.length; i++) {
      fn(i, _nodelist[i]);
    }
  }
  
  html([value]) {
      if (value == null)
        return _nodelist.length > 0 ? _nodelist[0].innerHTML : null;
      else
        each((idx, val) { val.innerHTML = value; });
      return this;
  }
  
  attr(key, [value]) {
      if (value == null)
        return _nodelist.length > 0 ? _nodelist[0].attributes[key] : null;
      else if (value is Map)
        value.forEach((k, itm) { each((idx, val) { val.attributes[k] = itm; } ); });
      else
        each((idx, val) => val.attributes[key] = value);
      return this;
  }
  
  click([value]) {
    if (value == null)
      each((idx, val) => val.on.click.dispatch(new Event('click')));
    else
      each((var idx, var val) => val.on.click.add(value));
    return this;
  }
  
  addClass(c_name) {
    if (c_name is String)
      each((var idx, var val) => val.classes.add(c_name));
    else { //assume it's a function
      for(var i = 0; i < _nodelist.length; i++) {
        _nodelist[i].classes.add(c_name(i, _nodelist[i]));
      }
    }
    return this;
  }
  
  hasClass(String c_name) {
    for(var i = 0; i < _nodelist.length; i++) {
      if (_nodelist[i].classes.contains(c_name))
        return true;
    }
    return false;
  }
  
  removeClass([String c_name]) {
    if (c_name == null)
      each((var idx, var val) => val.classes.clear());
    else {
      var classes = c_name.split(" ");
      classes.forEach((c) { each((var idx, var val) => val.classes.remove(c)); });
    }
    return this;
  }
  
  toggleClass(String c_name, [bool add_or_remove]) {
    if (add_or_remove != null) {
      if (add_or_remove) {
        this.addClass(c_name);
      }
      else {
        this.removeClass(c_name);
      }
    } else {
    var classes = c_name.split(" ");
    classes.forEach((c) { each((var idx, var val) { if (val.classes.contains(c)) val.classes.remove(c); else val.classes.add(c); }); });
    }
  }
  
}

//starting point for queries -> $(selector).xxxx
Dom $(var query) {
  if (query is String)
    return new Dom(document.queryAll(query));
  else if (query is NodeList)
    return new Dom(query);
  //assume if query is not a string or a NodeList, that it is a Node or an object with similar functions
  var nl = new List<Node>();
  nl.add(query);
  return new Dom(nl);
}

class qDart {
  
  now() {
    return new Date.now();
  }
  
}


main()
{
    //Test different features
    $("#status").html("qDart is <u>running</u> and <strong>works!</strong>");
    $("div").click( (e) {window.alert("you clicked on a div"); });
    $("div").click( (e) {$("div").toggleClass("some_css_class"); });
    $("div").addClass("some_css_class").removeClass("some_css_class");

}
